package com.rs2hd.net;

import com.rs2hd.model.*;
import com.rs2hd.net.Packet.Size;
import com.rs2hd.packetbuilder.StaticPacketBuilder;
import com.rs2hd.script.ScriptManager;
import org.apache.mina.common.IoFuture;
import org.apache.mina.common.IoFutureListener;
import com.rs2hd.util.Misc;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Set;
import com.rs2hd.io.XStreamPlayerLoader;

/**
 * Outgoing packets that we send so the end user does not have to mess with the builders.
 *
 * @author Graham
 */
public class ActionSender {

	private Player player;
	private int ID;

	public ActionSender(Player player) {
		this.ID = 0;
		this.player = player;
	}

	public void itemOnInterface(int interfaceid, int child, int amount, int itemid) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(145)
		.addInt(interfaceid << 16 | child)//Interface this should be in
		.addInt1(amount)//Amount to display, (Number next to pic)
		.addLEShortA(0)//Count
		.addLEShortA(itemid);//ITEM Id
		player.getSession().write(spb.toPacket());
	}
	public void animateInterface(int emoteId, int interfaceId, int childId) {
		player.getSession().write(new StaticPacketBuilder().setId(61).setSize(Packet.Size.VAR_BYTE)
				.addInt2(interfaceId << 16 | childId)
				.addLEShort(emoteId)
				.addLEShortA(0)
				.toPacket());
	}

	public void sendNpcHead(int npcId, int interfaceId, int childId) {
		player.getSession().write(new StaticPacketBuilder().setId(158).setSize(Packet.Size.VAR_BYTE)
				.addLEShortA(npcId)
				.addShort(0)
				.addInt2(interfaceId << 16 | childId)
				.toPacket());
	}

	public void sendPlayerHead(int interfaceId, int childId) {
		player.getSession().write(new StaticPacketBuilder().setId(219).setSize(Packet.Size.VAR_BYTE)
				.addShortA(0)
				.addInt1(interfaceId << 16 | childId)
				.toPacket());
	}

	public void sendCreateObject(int objectId, int height, int objectX, int objectY, int face, int type) {
		sendCoords(Location.location(objectX, objectY, player.getLocation().getZ()));
		int ot = ((type << 2) + (face & 3));
		player.getSession().write(new StaticPacketBuilder().setId(115)
				.addByteC((byte) 0)
				.addLEShortA(objectId)
				.addByteC((byte) ot).toPacket());
	}

	public void sendPlayerOption(String option, int slot, boolean top) {
		player.getSession().write(new StaticPacketBuilder().setId(73).setSize(Packet.Size.VAR_BYTE)
				.addLEShortA(65535)
				.addString(option)
				.addByteC(top ? 1 : 0)
				.addByteS(slot).toPacket());
	}

	public void sendSound(int sound, int volume, int delay) {
		player.getSession().write(new StaticPacketBuilder().setId(164)
				.addLEShortA(sound).addByte((byte) volume)
				.addLEShort(delay)
				.toPacket());
	}

	public void sendCloseInterface(int windowId, int position) {
		player.getSession().write(new StaticPacketBuilder().setId(203)
				.addShort(0)
				.addInt(windowId << 16 | position)
				.toPacket());
	}

	public void sendInterfaceConfig(int interfaceId, int childId, boolean set) {
		player.getSession().write(new StaticPacketBuilder().setId(3)
				.addShortA(0)
				.addByteS(set ? 1 : 0)
				.addInt2(interfaceId << 16 | childId)
				.toPacket());
	}

	public void sendBlankClientScript(int id) {
		StaticPacketBuilder packet = new StaticPacketBuilder().setId(70).setSize(Packet.Size.VAR_BYTE)
		.addShort(ID++)
		.addString("");
		packet.addInt(id);
		player.getSession().write(packet.toPacket());
	}
	public void setRightClickOptions(int set, int inter, int off, int len) {
		StaticPacketBuilder packet = new StaticPacketBuilder().setId(140)
		.addInt1(len)
		.addLEShortA(set)
		.addShortA(ID++)
		.addLEShortA(inter)
		.addLEShort(off);
		player.getSession().write(packet.toPacket());
	}

	public void sendInterface(int id, boolean isInventoryInterface) {
		sendCloseInterface();
		if (player.isHd()) {
			sendInterface(0, 746, isInventoryInterface ? 4 : 6, id); // 3 norm, 4 makes bank work, 6 makes help work
			sendInterface(0, 746, 8, id);
		} else {
			sendInterface(0, 548, 16, id);
		}
	}

	public void restoreTabs() {
		sendTab(150,  884); // Attack tab
		sendTab(151, 320); // Skill tab
		sendTab(152, 190); //  Quest tab
		sendTab(153, 259); //  Achievement tab
		sendTab(154, 149); // Inventory tab
		sendTab(155, 387); // Equipment tab
		sendTab(156, 271); // Prayer tab
		sendTab(157, 430); // Magic tab
		sendTab(159, 550); // Friend tab
		sendTab(160, 551); // Ignore tab
		sendTab(161, 589); // Clan tab
		sendTab(162, 261); // Setting tab
		sendTab(163, 464); // Emote tab
		sendTab(164, 187); // Music tab
		sendTab(165, 34); // Notes tab.
		sendTab(168, 182); // Logout tab
	}

	public void sendCloseInterface() {
		sendCloseInterface(548, 16);
	}

	public void sendInterface(int id) {
		sendCloseInterface();
		sendInterface(0, player.isFullScreen() ? 746 : 548, player.isFullScreen() ? 8 : 16, id);
	}

	public void sendQuestInterface(String title, String[] lines) {
		/*sendInterface(275, false);
	sendString(title, 275, 2);
	for(int i = 0; i < 300; i++) {
	    sendString("", 275, (i+11));
	}
	for(int i = 0; i < lines.length; i++) {
	    sendString(lines[i], 275, (i+11));
	}*/
	}

	public void sendSkillLevels() {
		for (int i = 0; i < Skills.SKILL_COUNT; i++) {
			sendSkillLevel(i);
		}
	}

	public void sendSkillLevel(int lvlId) {
		player.getSession().write(new StaticPacketBuilder().setId(38)
				.addByteA(player.getSkills().getLevel(lvlId))
				.addInt1((int) player.getSkills().getXp(lvlId))
				.addByteC(lvlId)
				.toPacket());
	}

	public void sendLogout() {
		player.getSession().write(new StaticPacketBuilder().setId(236).toPacket()).addListener(new IoFutureListener() {
			@Override
			public void operationComplete(IoFuture arg0) {
				arg0.getSession().close();
			}
		});
	}

	public void sendSystemUpdate(int time) {
		player.getSession().write(new StaticPacketBuilder().setId(231).addLEShort(time).toPacket());
	}
	public int set = 0;
	public void sendLogin() {
		sendMapRegion();
		sendWindowPane(548, 0);
		sendSkillLevels();
		sendMessage("Welcome to WinnerScape!");
		sendMessage("The Owner is <img=1><col=ff3300>Captain");
		sendMessage("The Co-Owner is <img=1><col=ff3300>Howbadisbad");
		sendMessage("The Head Java Programmer is <img=1>Emery");
		sendMessage("The Head Site Programmer is <img=1>Tom");
		sendMessage("-------------------------");
		sendMessage("Forums at http://WinnerScape.com/");
		sendMessage("Useful Commands, ::Dragpk, ::Edge, ::PkBox, ::Home, ::Kdr");
		sendMessage("Type :: to enter Commands.");
		//sendMessage("<col=ff3300>Blue Portal = Safe Zone, Red = Dangerous, Green = Safe MultiZone.");
		sendEnergy();
		sendConfig(300, 1000);
		highlightEmotes();
		player.getFriends().refresh();
		player.getInventory().refresh();
		player.getEquipment().refresh();
		//player.updateWildernessState();
		sendPlayerOption("Attack", 2, true);
		sendPlayerOption("Follow", 3, false);
		sendPlayerOption("Trade", 4, false);
		player.getActionSender().sendButtonGraphics(768, 3).sendButtonGraphics(
				768, 0).sendButtonGraphics(234, 0).sendButtonGraphics(
						181, 0).sendButtonGraphics(168, 4).sendButtonGraphics(
								234, 0).sendButtonGraphics(181, 0).sendButtonGraphics(
										695, 0).sendButtonGraphics(695, 0).setInterfaceConfig(
												34, 13, false).setInterfaceConfig(34, 13, false)
												.setInterfaceConfig(34, 3, false);

		ScriptManager.getInstance().invoke("login", player);
	}
	private void highlightEmotes() {
		sendConfig1(313, -1);
		sendConfig1(465, -1);
		sendConfig1(802, -1);
		sendConfig1(1085, 249852);
	}

	public void piesEquipment() {
		player.getInventory().addItem(11284, 1);
		player.getInventory().addItem(2581, 1);
		player.getInventory().addItem(6585, 1);
		player.getInventory().addItem(10378, 1);
		player.getInventory().addItem(10380, 1);
		player.getInventory().addItem(9751, 1);
		player.getInventory().addItem(3842, 1);
		player.getInventory().addItem(11732, 1);
		player.getInventory().addItem(7461, 1);
		player.getInventory().addItem(4151, 1);
		player.getInventory().addItem(11694, 1);
		player.getInventory().addItem(11726, 1);
		player.getInventory().addItem(11724, 1);
		player.getInventory().addItem(15259, 1);//D pick
		player.getInventory().addItem(10828, 1);
		player.getInventory().addItem(6570, 1);
		player.getInventory().addItem(9748, 1);
	}

	public void sendHdLogin() {
	}

	public void sendFriendsStatus(int i) {
		player.getSession().write(new StaticPacketBuilder().setId(5).addByte((byte) i).toPacket());
	}

	public void sendSentPrivateMessage(String name, String message) {
		byte[] bytes = new byte[message.length()];
		Misc.encryptPlayerChat(bytes, 0, 0, message.length(), message.getBytes());
		player.getSession().write(new StaticPacketBuilder().setId(92).setSize(Size.VAR_BYTE)
				.addString(Misc.upper2(name.replaceAll("_", " ")))
				.addByte((byte) message.length())
				.addBytes(bytes)
				.toPacket());
	}

	public void sendReceivedPrivateMessage(String name, int rights, String message) {
		int messageCounter = player.getFriends().getNextUniqueId();
		byte[] bytes = new byte[message.length()+1];
		bytes[0] = (byte) message.length();
		Misc.encryptPlayerChat(bytes, 0, 1, message.length(), message.getBytes());
		player.getSession().write(new StaticPacketBuilder().setId(226).setSize(Size.VAR_BYTE)
				.addByte((byte) 1)
				.addString(Misc.upper2(name.replaceAll("_", " ")))
				.addString(message)
				.addShort(12 + ID++)
				.addByte((byte) rights)
				.addBytes(new byte[] { (byte) ((messageCounter << 16) & 0xFF), (byte) ((messageCounter << 8) & 0xFF), (byte) (messageCounter & 0xFF)} )
				.addBytes(bytes)
				.toPacket());
	}
	private static int messageCounter = 1;
	public int index = 0, index2 = 0;
	public void sendClanChat(Player p2, String from, String clanName, String message) {//Gotta fix this
		if(messageCounter > 16000000) {
			messageCounter = 1;
		}
		byte[] bytes = new byte[message.length()+1];
		bytes[0] = (byte) message.length();
		Misc.encryptPlayerChat(bytes, 0, 1, message.length(), message.getBytes());
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(75).setSize(Size.VAR_BYTE);
		spb.addByte((byte)1)
		.addString(Misc.upper(from))
		.addString(Misc.upper(message))
		.addLong(Misc.stringToLong(clanName))
		.addShort(15);
		spb.addBytes(new byte[]{(byte) ((messageCounter << 16) & 0xFF),(byte) ((messageCounter << 8) & 0xFF), (byte) (messageCounter & 0xFF), 3, 0});
		spb.addBytes(bytes);
		messageCounter++;
		if (p2 != null) {
			spb.addByte((byte)p2.getRights());
		} else {
			spb.addByte((byte) 0);
		}
		spb.addShort(messageCounter + 10);
		player.getSession().write(spb.toPacket());
	}
	public void sendFriendOnline(String name, int world) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(20).setSize(Size.VAR_BYTE);
		spb.addByte((byte) 0)
		.addString(Misc.upper2(name.replaceAll("_", " ")))
		.addString("")
		.addShort(75)
		.addByte((byte) 0)
		.addString("<col=00FF00>Online")
		.addByte((byte) 1);
		player.getSession().write(spb.toPacket());
	}
	public void sendFriendOffline(String name, int world) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(20).setSize(Size.VAR_BYTE);
		spb.addByte((byte) 0)
		.addString(Misc.upper2(name.replaceAll("_", " ")))
		.addString(Misc.upper2(name.replaceAll("_", " ")))
		.addShort(0)
		.addByte((byte) 0);
		player.getSession().write(spb.toPacket());
	}
	public void sendChat() {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(91).setSize(Size.VAR_SHORT);
		spb.addString("Captain")//Owner Name
		.addByte((byte)1)//First Rank
		.addString("Test")//Idk yet
		.addLong(Misc.stringToLong("Lmao"))//Room name
		.addByte((byte) 2)//Amount of people in room
		.addByte((byte) 2)//Rank
		.addString("Coolio")//Player names
		.addByte((byte) 1)//IDK
		.addString("Runescape")//IDK
		.addShort(1)//Index
		.addByte((byte) 1)
		.addString("Final");//World ID
		player.getSession().write(spb.toPacket());
	}
	public void resetList() {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(91).setSize(Size.VAR_SHORT);
		player.getSession().write(spb.toPacket());
	}
	public void sendIgnores(String[] names) {
		/*StaticPacketBuilder spb = new StaticPacketBuilder().setId(20).setSize(Size.VAR_SHORT);
		for(String name : names) {
			spb.addString(name);
		}
		player.getSession().write(spb.toPacket());*/
	}

	/*public void sendMapRegion2() {
         if(!validateMapRegion()) {
             player.getActionSender().sendMessage("This area of the world is unavailable, teleporting to spawn point...");
             player.setLocation(Entity.DEFAULT_LOCATION);
             sendMapRegion();
             return;
         }
         StaticPacketBuilder spb = new StaticPacketBuilder().setId(173).setSize(Packet.Size.VariableShort);
         spb.addByteA(player.getLocation().getZ());
         spb.addShort(player.getLocation().getRegionY());
         spb.addShortA(player.getLocation().getLocalX());
         spb.initBitAccess();
         for(int height = 0; height < 4; height++) {
             for(int xCalc = (player.getLocation().getRegionX() - 6); xCalc <= (player.getLocation().getRegionX() + 6); xCalc++) {
                 for(int yCalc = (player.getLocation().getRegionY() - 6); yCalc <= (player.getLocation().getRegionY() + 6); yCalc++) {
                     if(height == player.getLocation().getZ()) {
                         spb.addBits(1, 1);
                         spb.addBits(26, (xCalc << 14) | (yCalc << 3));
                     } else {
                         spb.addBits(1, 0);
                     }
                 }
             }
         }
         spb.finishBitAccess();
         for(int xCalc = (player.getLocation().getRegionX() - 6) / 8; xCalc <= ((player.getLocation().getRegionX() + 6) / 8); xCalc++) {
             for(int yCalc = (player.getLocation().getRegionY() - 6) / 8; yCalc <= ((player.getLocation().getRegionY() + 6) / 8); yCalc++) {
                 int region = yCalc + (xCalc << 8);
                 int[] mapData = World.getInstance().getMapData(region);
                 if(mapData == null) {
                     mapData = new int[4];
                     for(int i = 0; i < 4; i++) {
                         mapData[i] = 0;
                     }
                 }
                 spb.addInt(mapData[0]);
                 spb.addInt(mapData[1]);
                 spb.addInt(mapData[2]);
                 spb.addInt(mapData[3]);
             }
         }
         spb.addShortA(player.getLocation().getLocalY());
         spb.addShortA(player.getLocation().getRegionX());
         player.getSession().write(spb.toPacket());
         player.getUpdateFlags().setLastRegion(player.getLocation());
         World.getInstance().getItemManager().refresh(player);
     }*/

	public void sendMapRegion() {
		if(!validateMapRegion()) {
			player.tele(3428, 2891, 0);
			return;
		}
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(76).setSize(Packet.Size.VAR_SHORT);
		boolean forceSend = true;
		spb.addLEShortA(player.getLocation().getRegionX());
		spb.addShort(player.getLocation().getLocalY());
		spb.addByte((byte) 0);
		spb.addByteA(0);
		if ((((player.getLocation().getRegionX() / 8) == 48) || ((player.getLocation().getRegionX() / 8) == 49)) && ((player.getLocation().getRegionY() / 8) == 48)) {
			forceSend = false;
		}
		if (((player.getLocation().getRegionX() / 8) == 48) && ((player.getLocation().getRegionY() / 8) == 148)) {
			forceSend = false;
		}
		for (int xCalc = (player.getLocation().getRegionX() - 6) / 8; xCalc <= ((player.getLocation().getRegionX() + 6) / 8); xCalc++) {
			for (int yCalc = (player.getLocation().getRegionY() - 6) / 8; yCalc <= ((player.getLocation().getRegionY() + 6) / 8); yCalc++) {
				int region = yCalc + (xCalc << 8); // 1786653352
				if (forceSend || ((yCalc != 49) && (yCalc != 149) && (yCalc != 147) && (xCalc != 50) && ((xCalc != 49) || (yCalc != 47)))) {
					int[] mapData = World.getInstance().getMapData(region);
					spb.addInt(mapData[0]);
					spb.addInt(mapData[1]);
					spb.addInt(mapData[2]);
					spb.addInt(mapData[3]);
				}
			}
		}
		spb.addByteA(player.getLocation().getZ());
		spb.addShort(player.getLocation().getLocalX());
		spb.addShort(player.getLocation().getRegionY());
		player.getSession().write(spb.toPacket());
		player.getUpdateFlags().setLastRegion(player.getLocation());
		//World.getInstance().getItemManager().refresh(player);
	}

	private boolean validateMapRegion() {
		boolean hasMapData = true;
		boolean forceSend = true;
		if ((((player.getLocation().getRegionX() / 8) == 48) || ((player.getLocation().getRegionX() / 8) == 49)) && ((player.getLocation().getRegionY() / 8) == 48)) {
			forceSend = false;
		}
		if (((player.getLocation().getRegionX() / 8) == 48) && ((player.getLocation().getRegionY() / 8) == 148)) {
			forceSend = false;
		}
		for (int xCalc = (player.getLocation().getRegionX() - 6) / 8; xCalc <= ((player.getLocation().getRegionX() + 6) / 8); xCalc++) {
			for (int yCalc = (player.getLocation().getRegionY() - 6) / 8; yCalc <= ((player.getLocation().getRegionY() + 6) / 8); yCalc++) {
				int region = yCalc + (xCalc << 8); // 1786653352
				if (forceSend || ((yCalc != 49) && (yCalc != 149) && (yCalc != 147) && (xCalc != 50) && ((xCalc != 49) || (yCalc != 47)))) {
					int[] mapData = World.getInstance().getMapData(region);
					if (mapData == null) {
						hasMapData = false;
					}
				}
			}
		}
		return hasMapData;
	}

	public void sendWindowPane(int pane, int subWindows) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(50).addShortA(pane).addShort(0).addByteS(subWindows);
		player.getSession().write(spb.toPacket());
	}
	public ActionSender setWindow(int pane, int subWindows) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(50).addShortA(pane).addShort(0).addByteS(subWindows);
		player.getSession().write(spb.toPacket());
		return this;
	}

	public void sendTab(int tabId, int childId) {
		if (player.isHd()) {
			sendInterface(1, childId == 137 ? 752 : 746, tabId, childId);
		} else {
			sendInterface(1, childId == 137 ? 752 : 548, tabId, childId);
		}
	}

	public void sendConfig(int id, int value) {
		if (value < 128) {
			sendConfig1(id, value);
		} else {
			sendConfig2(id, value);
		}
	}

    public void sendConfig3(int id, int set) {
        if (set < Byte.MIN_VALUE || set > Byte.MAX_VALUE) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(151)
                    .addLEInt(set)
                    .addShort(id);
        } else {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(186)
                    .addByteS(set)
                    .addLEShortA(id);
        }
    }

	public void sendConfig1(int id, int value) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(186)
		.addByteS((byte) value)
		.addLEShortA(id);
		player.getSession().write(spb.toPacket());
	}

	public void sendConfig2(int id, int value) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(151)
		.addLEInt(value)
		.addShort(id);
		player.getSession().write(spb.toPacket());
	}
	public void sendMessage(String message) {
		if (message.equals("Welcome to RuneScape.")) {
			return;
		}
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(193).setSize(Size.VAR_BYTE)
		.addSmart(0)
		.addInt(0)
		.addByte((byte) 0)
		.addString(message);
		player.getSession().write(spb.toPacket());
	}
	public void sendTradeReq(String user, String message) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(193).setSize(Size.VAR_BYTE)
		.addSmart(4)
		.addInt(0)
		.addByte((byte) 1)
		.addString(user)
		.addString(message);
		player.getSession().write(spb.toPacket());
	}

	public void sendItems(int interfaceId, int childId, int type, Container<Item> inventory) {
		int main = interfaceId * 65536 + childId;
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(120).setSize(Size.VAR_SHORT);
		spb.addInt(main)
		.addShort(type)
		.addShort(inventory.getSize());
		for (int i = 0; i < inventory.getSize(); i++) {
			Item item = inventory.get(i);
			int id, amt;
			if (item == null) {
				id = -1;
				amt = 0;
			} else {
				id = item.getDefinition().getId();
				amt = item.getAmount();
			}
			if (amt > 254) {
				spb.addInt1(255);
                //amt = 254;
				spb.addByteC(amt);
			} else {
				spb.addByteC(amt);
			}
			spb.addLEShort(id + 1);
		}
		player.getSession().write(spb.toPacket());
	}


	public void sendString(String string, int interfaceId, int childId) {
		string = "  " + string;
		int sSize = string.length() + 5;
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(106)
		.addByte((byte) (sSize / 256))
		.addByte((byte) (sSize % 256))
		.addString(string)
		.addInt2(interfaceId << 16 | childId);
		player.getSession().write(spb.toPacket());
	}
	public void sendInterface(int showId, int windowId, int interfaceId, int childId) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(56)
		.addShort(childId)
		.addByteS(showId)
		.addShort(ID++)
		.addLEInt(windowId << 16|interfaceId);
		player.getSession().write(spb.toPacket());
	}
	public ActionSender setInterface(int showId, int windowId, int interfaceId, int childId) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(56)
		.addShort(childId)
		.addByteS(showId)
		.addShort(ID++)
		.addLEInt(windowId << 16|interfaceId);
		player.getSession().write(spb.toPacket());
		return this;
	}
	public void sendChatboxInterface(int childId) {
		sendInterface(1, 752, 8, childId);
		//sendInterface(1, 751, 8, childId);
		//sendInterface(1, 752, 8, 137); // Playername on chat
	}

	public void sendCloseChatboxInterface() {
		sendInterface(1, 752, 8, 140);

		//sendTab(140, 752);
		//sendCloseInterface(752, 12);
	}

	public void sendInventoryInterface(int childId) {
		if (player.isHd()) {
			sendInterfaceConfig(746, 8, false);
		} else {
			sendInterfaceConfig(548, 8, false);
		}
		if (player.isHd()) {
			sendInterface(0, 746, 145, childId);
		} else {
			sendInterface(0, 548, 145, childId);
		}
	}

	public void sendCloseInventoryInterface() {
		if(player.isHd()) {
			sendInterfaceConfig(746, 8, true);
		} else {
			sendInterfaceConfig(548, 145, true);
		}
	}

	public void sendShopTab(boolean isMainStock, boolean isGeneralStore) {
		// player.getActionSender().sendInterfaceConfig(620, 24, true); - main inv screen
		if (isMainStock) {
			player.getActionSender().sendInterfaceConfig(620, 23, false);
			player.getActionSender().sendInterfaceConfig(620, 29, false);
			player.getActionSender().sendInterfaceConfig(620, 25, true);
			player.getActionSender().sendInterfaceConfig(620, 27, true);
			player.getActionSender().sendInterfaceConfig(620, 26, false);
		} else {
			player.getActionSender().sendInterfaceConfig(620, 23, true);
			player.getActionSender().sendInterfaceConfig(620, 29, true);
			player.getActionSender().sendInterfaceConfig(620, 25, false);
			player.getActionSender().sendInterfaceConfig(620, 27, false);
			player.getActionSender().sendInterfaceConfig(620, 26, true);
		}
		if (isGeneralStore) {
			player.getActionSender().sendInterfaceConfig(620, 34, false);
		} else {
			player.getActionSender().sendInterfaceConfig(620, 34, true);
		}
	}

	public void sendShopOptions() {
				StaticPacketBuilder spb = new StaticPacketBuilder().setId(223)
				.addShort(10)
				.addLEShortA(0)
				.addLEShort(23)
				.addLEShort(620)
				.addLEShort(126)
				.addLEShort(0);
				//player.getSession().write(spb.toPacket());
				spb = new StaticPacketBuilder().setId(152).setSize(Size.VAR_SHORT)
				.addString("IviiiIsssssssss")
				.addString("null")
				.addString("null")
				.addString("null")
				.addString("Examine")
				.addString("Sell 50")
				.addString("Sell 10")
				.addString("Sell 5")
				.addString("Sell 1")
				.addString("Value")
				.addInt(-1)
				.addInt(0)
				.addInt(7)
				.addInt(4)
				.addInt(93)
				.addInt(40697856)
				.addInt(150);
				player.getSession().write(spb.toPacket());
				spb = new StaticPacketBuilder().setId(223)
				.addShort(27)
				.addLEShortA(0)
				.addLEShort(0)
				.addLEShort(621)
				.addLEShort(126)
				.addLEShort(0);
				player.getSession().write(spb.toPacket());
				spb = new StaticPacketBuilder().setId(152).setSize(Size.VAR_SHORT)
				.addString("IviiiIsssssssss")
				.addString("null")
				.addString("null")
				.addString("null")
				.addString("null")
				.addString("Buy 50")
				.addString("Buy 10")
				.addString("Buy 5")
				.addString("Buy 1")
				.addString("Value")
				.addInt(-1)
				.addInt(0)
				.addInt(4)
				.addInt(10)
				.addInt(17)
				.addInt(40632344)
				.addInt(150);
				player.getSession().write(spb.toPacket());
				spb = new StaticPacketBuilder().setId(223)
				.addShort(39)
				.addLEShortA(0)
				.addLEShort(24)
				.addLEShort(620)
				.addLEShort(1086)
				.addLEShort(0);
				player.getSession().write(spb.toPacket());
	}
	public void blackCompass(int i) {
		player.getSession().write(new StaticPacketBuilder().setId(208).addByte((byte) i));
	}
	public void sendEnergy() {
		player.getSession().write(new StaticPacketBuilder().setId(63)
				.addByte((byte) player.getRunEnergy()).toPacket());
	}

	public void sendCoords(Location location) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(207);
		int regionX = player.getUpdateFlags().getLastRegion().getRegionX(), regionY = player.getUpdateFlags().getLastRegion().getRegionY();
		spb.addByteS((byte) (location.getY()-((regionY-6)*8)));
		spb.addByte((byte) (location.getX()-((regionX-6)*8)));
		player.getSession().write(spb.toPacket());
	}
	public void setCoords(int x, int y) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(207);
		spb.addByteS(y);
		spb.addByte((byte) x);
		player.getSession().write(spb.toPacket());
	}
	public void sendCoords(Location location, int xoff, int yoff) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(207);
		int regionX = player.getUpdateFlags().getLastRegion().getRegionX(), regionY = player.getUpdateFlags().getLastRegion().getRegionY();
		spb.addByteS((byte) ((location.getY()-((regionY-6)*8))+yoff));
		spb.addByte((byte) ((location.getX()-((regionX-6)*8))+xoff));
		player.getSession().write(spb.toPacket());
	}

	public void sendDestroyGroundItem(FloorItem item) {
		sendCoords(item.getLocation());
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(221);
		spb.addByteS((byte) 0);
		spb.addShort(item.getId());
		player.getSession().write(spb.toPacket());
	}

	public void sendCreateGroundItem(FloorItem item) {
		sendCoords(item.getLocation());
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(22);
		spb.addLEShortA(item.getAmount());
		spb.addShort(item.getId());
		spb.addByteC(0);
		player.getSession().write(spb.toPacket());
	}

	public void switchPanes(int paneFrom, int windowPosFrom, int paneTo, int windowPosTo) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(206);
		spb.addLEShort(0)
		.addLEInt(paneFrom << 16 | windowPosFrom)
		.addInt2(paneTo << 16 | windowPosTo);
		player.getSession().write(spb.toPacket());
	}
	public ActionSender switchPanes2(int paneFrom, int windowPosFrom, int paneTo, int windowPosTo) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(206);
		spb.addLEShort(0)
		.addLEInt(paneFrom << 16 | windowPosFrom)
		.addInt2(paneTo << 16 | windowPosTo);
		player.getSession().write(spb.toPacket());
		return this;
	}

	public void sendBonus(int[] bonuses) {
		int id = 35;
		for (int i = 0; i < (bonuses.length - 1); i++) {
			sendString((Bonuses.BONUS_NAMES[i] + ": " + (bonuses[i] > 0 ? "+" : "") + bonuses[i]), 667, id++);
			if (id == 45) {
				sendString((Bonuses.BONUS_NAMES[12] + ": " + (bonuses[12] > 0 ? "+" : "") + bonuses[12]), 667, id++);
				id = 47;
			}
		}
	}

	public void sendShopLoadMainStock(int shopId) {
		/*		StaticPacketBuilder spb = new StaticPacketBuilder().setId(152).setSize(Size.VAR_SHORT)
		.addString("vg")
		.addInt(shopId)
		.addInt(93)
		.addInt(25);
		player.getSession().write(spb.toPacket());*/
	}

	public void sendOverlay(int i) {
		if (player.isHd()) {
			sendInterface(1, 746, 5, i);
		} else {
			sendInterface(1, 548, 5, i);
		}
	}

	public void sendRemoveOverlay() {
		if (player.isHd()) {
			sendCloseInterface(746, 5);
		} else {
			sendCloseInterface(548, 5);
		}
	}
	public void sendGlobalProjectile(int casterY, int casterX, int offsetY, int offsetX, int gfxMoving, int startHeight, int endHeight, int Z, int D, int A, int speed, int atkIndex) {
		for (Player pl : World.getInstance().getPlayerList()) {
			if (pl == null) {
				continue;
			}
			pl.getActionSender().sendProjectile2(casterY, casterX, offsetY, offsetX, 50, speed, gfxMoving, startHeight, endHeight, Z, D, A, atkIndex);
		}
	}
	public void sendProjectile2(int casterY, int casterX, int offsetY, int offsetX, int angle,
			int speed, int gfxMoving, int startHeight, int endHeight, int Z, int D, int A, int lockon) {
		setCoords((casterX - ((player.getLocation().getRegionX() - 6) * 8)) - 3,(casterY - ((player.getLocation().getRegionY() - 6) * 8)) - 2);
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(212)
		.addByte((byte) angle)
		.addByte((byte) offsetX)
		.addByte((byte) offsetY)
		.addShort(lockon)
		.addShort(gfxMoving)
		.addByte((byte) startHeight)
		.addByte((byte) endHeight)
		.addShort(D)
		.addShort(speed)
		.addByte((byte) A)
		.addByte((byte) Z);
		player.getSession().write(spb.toPacket());
	}
	public void switchMagic(Player p) {
		System.out.println(p.magicType);
		// Magic tab
		if(p.magicType == 192 || p.magicType == 0) {
			sendMessage("You convert to Ancient Magics.");
			sendTab(157, 193);
			p.magicType = 193;
		}
		else if(p.magicType == 193) {
			sendMessage("You convert to Lunar Magics.");
			sendTab(157, 430);
			p.magicType = 430;
		}
		else if(p.magicType == 430) {
			sendMessage("You convert to Modern Magics.");
			sendTab(157, 192);
			p.magicType = 192;
		}

	}
	public void sendProjectile(Location source, Location dest, int offsetX, int offsetY, int angle, int speed, int gfxMoving, int startHeight, int endHeight, Entity lockon) {
		sendCoords(source, -3, -2);
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(212)
		.addByte((byte) angle)
		.addByte((byte) offsetX) 
		.addByte((byte) offsetY)
		.addShort(lockon == null ? -1 : (lockon instanceof Player ? - lockon.getClientIndex() - 1 : lockon.getClientIndex() + 1))
		.addShort(gfxMoving)
		.addByte((byte) startHeight)
		.addByte((byte) endHeight)
		.addShort(51)
		.addShort(speed)
		.addByte((byte) 16)
		.addByte((byte) 64);
		player.getSession().write(spb.toPacket());
	}
	public void sendTradeOptions() {
		this.sendAccessMask(1026, 335, 30, 0, 27);
		this.sendAccessMask(1026, 335, 32, 0, 27);
		this.sendAccessMask(1278, 336, 0, 0, 27);
		Object[] tparams1 = new Object[]{"", "", "", "Value<col=FF9040>", "Remove-X", "Remove-All", "Remove-10", "Remove-5", "Remove", -1, 0, 7, 4, 90, 21954590};
		Object[] tparams2 = new Object[]{"", "", "Lend", "Value<col=FF9040>", "Offer-X", "Offer-All", "Offer-10", "Offer-5", "Offer", -1, 0, 7, 4, 93, 22020096};
		Object[] tparams3 = new Object[]{"", "", "", "", "", "", "", "", "Value<col=FF9040>", -1, 0, 7, 4, 90, 21954592};
		this.sendRunScript(150, tparams1, "IviiiIsssssssss");
		this.sendRunScript(150, tparams2, "IviiiIsssssssss");
		this.sendRunScript(695, tparams3, "IviiiIsssssssss");
	}
	public void search(Object[] o) {
	   sendConfig1(1109, -1);
	   sendConfig1(1112, 0);
	   sendConfig1(1113, 0);
	   sendInterface(6, 752, 6, 389);
       StaticPacketBuilder spb = new StaticPacketBuilder().setId(70).setSize(Size.VAR_SHORT);
       spb.addString("");
	   String valstring = "s";
       int j = 0;
       for (int i = valstring.length() - 1;i >= 0;i--) {
			if (valstring.charAt(i) == 's') 
                 spb.addString(((String) o[j]));
            else
               spb.addInt((Integer) o[j]);
            }
            j++;
			spb.addInt(570);
		player.getSession().write(spb.toPacket());
	}
	public void sendRunScript(int id, Object[] params, String types) {
		if (params.length != types.length())
			throw new IllegalArgumentException("params size should be the same as types length");
		StaticPacketBuilder packet = new StaticPacketBuilder().setId(70).setSize(Size.VAR_SHORT)
		.addShort(ID++)
		.addString(types);
		int idx = 0;
		for (int i = types.length() - 1;i >= 0;i--) {
			if (types.charAt(i) == 's') 
				packet.addString((String) params[idx]);
			else
				packet.addInt((Integer) params[idx]);
			idx++;
		}
		packet.addInt(id);
		player.getSession().write(packet.toPacket());
	}


	public void sendBankOptions() {
		sendAccessMask(2622718, 762, 81, 0, 496);
		sendAccessMask(2360446, 763, 0, 0, 27);
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(70)
		.addShort(0)
		.addString("")
		.addInt(1451);
		player.getSession().write(spb.toPacket());
	}

	public void sendAccessMask(int set, int inter, int child, int off, int len) {
		StaticPacketBuilder packet = new StaticPacketBuilder().setId(113)
		.addInt(set) 
		.addLEShort(len)
		.addLEShort(off)
		.addLEShortA(ID++) 
		.addLEInt(inter << 16 | child);
		player.getSession().write(packet.toPacket());
	}

	public void sendTabs() {
		for (int i = 16; i <= 21; i++) {
			player.getActionSender().sendInterfaceConfig(player.isHd() ? 746 : 548, i, false);
		}
		for (int i = 32; i <= 38; i++) {
			player.getActionSender().sendInterfaceConfig(player.isHd() ? 746 : 548, i, false);
		}
		player.getActionSender().sendInterfaceConfig(player.isHd() ? 746 : 548, 14, false);
		player.getActionSender().sendInterfaceConfig(player.isHd() ? 746 : 548, 31, false);
		player.getActionSender().sendInterfaceConfig(player.isHd() ? 746 : 548, 63, false);
		player.getActionSender().sendInterfaceConfig(player.isHd() ? 746 : 548, 72, false);
	}

	public void sendAccessMask(int set1, int set2, int interfaceId1, int childId1, int interfaceId2, int childId2) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(113);
		spb.addInt(interfaceId2 << 16 | childId2)
		.addLEShort(set2)
		.addLEShort(set1)
		.addLEShortA(0)
		.addLEInt(interfaceId1 << 16 | childId1);
		player.getSession().write(spb.toPacket());
	}
	public ActionSender setAccessMask(int set1, int set2, int interfaceId1, int childId1, int interfaceId2, int childId2) {
		StaticPacketBuilder spb = new StaticPacketBuilder().setId(113);
		spb.addInt(interfaceId2 << 16 | childId2)
		.addLEShort(set2)
		.addLEShort(set1)
		.addLEShortA(0)
		.addLEInt(interfaceId1 << 16 | childId1);
		player.getSession().write(spb.toPacket());
		return this;
	}
	public ActionSender sendButtonGraphics(int type, int amount) {
		StaticPacketBuilder spb = new StaticPacketBuilder();
		if (amount < Byte.MIN_VALUE || amount > Byte.MAX_VALUE) {
			spb.setId(21).addLEShortA(type).addInt1(amount).addShort(0);
		} else {
			spb.setId(164).addLEShortA(0).addByte((byte)amount).addLEShort(type);
		}
		player.getSession().write(spb.toPacket());
		return this;
	}
	public void dunno(int int2, int int3) {
		player.getSession().write(new StaticPacketBuilder().setId(21)
				.addLEShortA(int2)
				.addInt1((byte)int3)
				.addLEShort(0)
				.toPacket());
	}	
	public ActionSender setInterfaceConfig(int interfaceId, int childId, boolean set) {
		StaticPacketBuilder spb = new StaticPacketBuilder();
		spb.setId(3);
		spb.addShortA(0)
		.addByteS(set ? 1 : 0)
		.addInt2(interfaceId << 16 | childId);
		player.getSession().write(spb.toPacket());
		return this;
	}
}
